package com.logic.modular.game.battle.process.skillEffectHandle.impl;

import com.logic.modular.game.battle.panel.skillEffect.PvpSkillEffectServiceImpl;
import com.logic.modular.game.battle.panel.skillEffect.domain.SkillEffectLayer;
import com.logic.modular.game.battle.process.battleStage.actionPhase.actionPhase2.item.ReleaseSkillService2;
import com.logic.modular.game.battle.process.domain.Reason;
import com.logic.modular.game.battle.process.skillEffectHandle.base.BaseSkillEffectStrategy;
import com.logic.modular.game.battle.panel.attribute.domain.PlayerHeroAttribute;
import com.logic.modular.game.battle.panel.skillEffect.PvpSkillEffect;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;


@Component
public class BloodVolumeStrategy {
    @Slf4j
    @Component
    public static class BaseBloodVolumeStrategy extends BaseSkillEffectStrategy {
        @Override
        public PvpSkillEffect applyEffect(PvpSkillEffect pvpSkillEffect) {
            effectHandle2.tryTriggerJudgment(pvpSkillEffect);
            effectHandle2.logTriggerFailReasons(pvpSkillEffect);
            apply(pvpSkillEffect);
            return pvpSkillEffect;
        }

        @Override
        public PvpSkillEffect apply(PvpSkillEffect pvpSkillEffect) {
            return null;
        }
    }


    @Slf4j
    @Component
    public static class RecoverStrategy extends BaseBloodVolumeStrategy {
        public PvpSkillEffect apply(
                PvpSkillEffect pvpSkillEffect
        ) {
            Integer status = pvpSkillEffect.status.getStatus();
            if (pvpSkillEffect.status.getIsTrigger() != 1) {
                Reason reason = new Reason();
                reason.setSuccess(false);
                reason.setType(status);
                reason.setReasonSource(null);
                pvpSkillEffect.skillEffectTriggerInfo.setReason(reason);
                pvpSkillEffect.skillEffectTriggerInfo.setSkillEffectLayer(new ArrayList<>());
                attributeService.refreshPanel(pvpSkillEffect);
                return pvpSkillEffect;
            }
            String battleUUID = pvpSkillEffect.getBattleUUID();
            Long battleId = pvpSkillEffect.getBattleId();
            Long sourcePlayerHeroId = pvpSkillEffect.getSourcePlayerHeroId();
            Long targetPlayerHeroId = pvpSkillEffect.getTargetPlayerHeroId();
            PlayerHeroAttribute sourceAttribute = this.attributeService.get(battleUUID, sourcePlayerHeroId);
            Long coreSkillEffectTypeId = pvpSkillEffect.getCoreSkillEffectTypeId();
            String fieldName = pvpSkillEffect.getSkillEffectLayer().getName();
            Integer isMagic = pvpSkillEffect.getIsMagic();
            Integer trigger6 = pvpSkillEffect.getBaseTrigger().getTrigger6();

            List<PlayerHeroAttribute> targetHeroes =
                    releaseSkillService2.getTargetHeroes(battleUUID, targetPlayerHeroId, trigger6);
            for (PlayerHeroAttribute targetAttribute : targetHeroes) {
                double value = pvpSkillEffect.getMagicInfluence() / 100.0;
                double strategy = coreCombatFormulaService.getRealRecover(
                        sourceAttribute.getCurrentForce(),
                        sourceAttribute.getMagic(),
                        sourceAttribute.obtainRecoverIncrease() - targetAttribute.obtainRecoverDecrease(),
                        targetAttribute.getLastDead(),
                        targetAttribute.getThisDead(),
                        1,
                        value,
                        isMagic
                );
                log.info(
                        "恢复兵力,武将:{}兵力:{}----->目标{}",
                        sourceAttribute.getId(),
                        sourceAttribute.getCurrentForce(),
                        targetAttribute.getId()
                );
                Object attributeUpdate = targetAttribute.attributeUpdate(
                        fieldName,
                        strategy,
                        0,
                        1,
                        coreSkillEffectTypeId);
                sourceAttribute.attributeUpdate(
                        fieldName,
                        strategy,
                        1,
                        1,
                        coreSkillEffectTypeId);
                this.attributeService.saveCache(sourceAttribute);
                this.attributeService.saveCache(targetAttribute);

                log.info(
                        "物理攻击,武将:{}兵力:{}----->目标{}",
                        sourceAttribute.getId(),
                        sourceAttribute.getCurrentForce(),
                        targetAttribute.getId()
                );
                this.attributeService.saveCache(sourceAttribute);
                this.attributeService.saveCache(targetAttribute);
                effectHandle2.effectTriggerBy(fieldName, sourceAttribute, targetAttribute);

                SkillEffectLayer build = SkillEffectLayer.builder()
                        .targetPlayerHeroId(targetAttribute.getId())
                        .thisChangeValue(strategy)
                        .name(pvpSkillEffect.getSkillEffectLayer().getName())
                        .thisChangeValue(strategy)
                        .lastEndValue(attributeUpdate)
                        .build();
                pvpSkillEffect.setSkillEffectLayer(build);
            }
            pvpSkillEffect.status.addTriggers(1);
            attributeService.refreshPanel(pvpSkillEffect);
            return pvpSkillEffect;
        }
    }

    /**
     * 51	发动一次物理攻击
     * 发动一次物理攻击
     */
    @Slf4j
    @Component
    public static class BloodVolume51 extends BaseBloodVolumeStrategy {
        @Resource
        private PvpSkillEffectServiceImpl skillEffectService;
        @Resource
        private ReleaseSkillService2 releaseSkillService2;

        /**
         * 发动一次物理伤害
         */
        public PvpSkillEffect apply(
                PvpSkillEffect pvpSkillEffect
        ) {
            if (pvpSkillEffect.status.getIsTrigger() != 1) {
                attributeService.refreshPanel(pvpSkillEffect);
                return pvpSkillEffect;
            }
            String battleUUID = pvpSkillEffect.getBattleUUID();
            Long battleId = pvpSkillEffect.getBattleId();
            Integer trigger6 = pvpSkillEffect.getBaseTrigger().getTrigger6();
            Long sourcePlayerHeroId = pvpSkillEffect.getSourcePlayerHeroId();
            Long targetPlayerHeroId = pvpSkillEffect.getTargetPlayerHeroId();
            Long coreSkillEffectTypeId = pvpSkillEffect.getCoreSkillEffectTypeId();
            String fieldName = pvpSkillEffect.getSkillEffectLayer().getName();
            double value = pvpSkillEffect.getMagicInfluence() / 100.0;

            PlayerHeroAttribute sourceAttribute = this.attributeService.get(battleUUID, sourcePlayerHeroId);
            Long currentForce = sourceAttribute.getCurrentForce();
            Double att = sourceAttribute.getAtt();
            Double igPhysicalDefense = sourceAttribute.getIgPhysicalDefense();

            List<PlayerHeroAttribute> targetHeroes =
                    releaseSkillService2.getTargetHeroes(battleUUID, targetPlayerHeroId, trigger6);

            for (PlayerHeroAttribute targetAttribute : targetHeroes) {
                double physicsAttackIncrease =
                        sourceAttribute.obtainPhysicsAttackIncrease() - targetAttribute.obtainPhysicsAttackDecrease();
                Double def = targetAttribute.getDef();
                double physics = -coreCombatFormulaService.getPhysics(
                        currentForce,
                        att,
                        igPhysicalDefense,
                        value,
                        physicsAttackIncrease,
                        def
                );

                log.info(
                        "物理攻击,武将:{}兵力:{}----->目标{}",
                        sourceAttribute.getId(),
                        sourceAttribute.getCurrentForce(),
                        targetAttribute.getId()
                );
                Object targetBlood = targetAttribute.bloodDeduction(physics, 0, 1, coreSkillEffectTypeId);
                sourceAttribute.bloodDeduction(physics, 1, 1, coreSkillEffectTypeId);
                this.attributeService.saveCache(sourceAttribute);
                this.attributeService.saveCache(targetAttribute);
                effectHandle2.effectTriggerBy(fieldName, sourceAttribute, targetAttribute);

                SkillEffectLayer build = SkillEffectLayer.builder()
                        .targetPlayerHeroId(targetAttribute.getId())
                        .thisChangeValue(physics)
                        .name(pvpSkillEffect.getSkillEffectLayer().getName())
                        .thisChangeValue(physics)
                        .lastEndValue(targetBlood)
                        .build();
                pvpSkillEffect.setSkillEffectLayer(build);
            }
            pvpSkillEffect.status.addTriggers(1);
            attributeService.refreshPanel(pvpSkillEffect);
            return pvpSkillEffect;
        }
    }

    /**
     * 52	发动一次策略攻击
     * 发动一次策略攻击
     */
    @Slf4j
    @Component
    public static class StrategyStrategy extends BaseBloodVolumeStrategy {
        public PvpSkillEffect apply(
                PvpSkillEffect pvpSkillEffect
        ) {
            if (pvpSkillEffect.status.getIsTrigger() != 1) {
                attributeService.refreshPanel(pvpSkillEffect);
                return pvpSkillEffect;
            }

            String battleUUID = pvpSkillEffect.getBattleUUID();
            Long battleId = pvpSkillEffect.getBattleId();
            Long sourcePlayerHeroId = pvpSkillEffect.getSourcePlayerHeroId();
            Long targetPlayerHeroId = pvpSkillEffect.getTargetPlayerHeroId();
            PlayerHeroAttribute sourceAttribute = attributeService.get(battleUUID, sourcePlayerHeroId);
            Integer trigger6 = pvpSkillEffect.getBaseTrigger().getTrigger6();
            Long coreSkillEffectTypeId = pvpSkillEffect.getCoreSkillEffectTypeId();
            String fieldName = pvpSkillEffect.getSkillEffectLayer().getName();
            Integer isMagic = pvpSkillEffect.getIsMagic();
            double value = pvpSkillEffect.getMagicInfluence() / 100.0;
            Long currentForce = sourceAttribute.getCurrentForce();
            Double magic = sourceAttribute.getMagic();
            double igStrategicDefense = sourceAttribute.getIgStrategicDefense() + sourceAttribute.getIgDefensiveDefense();

            List<PlayerHeroAttribute> targetHeroes =
                    releaseSkillService2.getTargetHeroes(battleUUID, targetPlayerHeroId, trigger6);
            for (PlayerHeroAttribute targetAttribute : targetHeroes) {
                double strategyAttackIncrease =
                        sourceAttribute.obtainStrategyAttackIncrease() - targetAttribute.obtainStrategyAttackDecrease();
                Double targetAttributeMagic = targetAttribute.getMagic();

                double physics = -coreCombatFormulaService.getStrategy(
                        currentForce,
                        magic,
                        igStrategicDefense,
                        1,
                        value,
                        isMagic,
                        strategyAttackIncrease,
                        targetAttributeMagic
                );
                log.info(
                        "策略攻击,武将:{}兵力:{}----->目标{}",
                        sourceAttribute.getId(),
                        sourceAttribute.getCurrentForce(),
                        targetAttribute.getId()
                );
                Object targetBlood = targetAttribute.bloodDeduction(physics, 0, 1, coreSkillEffectTypeId);
                sourceAttribute.bloodDeduction(physics, 1, 1, coreSkillEffectTypeId);
                attributeService.saveCache(sourceAttribute);
                attributeService.saveCache(targetAttribute);

                effectHandle2.effectTriggerBy(fieldName, sourceAttribute, targetAttribute);

                SkillEffectLayer build = SkillEffectLayer.builder()
                        .targetPlayerHeroId(targetAttribute.getId())
                        .thisChangeValue(physics)
                        .name(pvpSkillEffect.getSkillEffectLayer().getName())
                        .thisChangeValue(physics)
                        .lastEndValue(targetBlood)
                        .build();
                pvpSkillEffect.setSkillEffectLayer(build);
            }
            pvpSkillEffect.status.addTriggers(1);
            attributeService.refreshPanel(pvpSkillEffect);
            return pvpSkillEffect;
        }
    }
}
